#ifndef TINX_ACPI_H
#define TINX_ACPI_H

#include <tinx/types.h>

typedef struct ACPI_RSDPtr
{
    char Signature[8];
    u8 Checksum;
    char OEMID[6];
    u8 Revision;
    u32 RsdtAddress;
} _packed RSDPtr;

typedef struct ACPISDTHeader
{
    char Signature[4];
    u32 Length;
    u8 Revision;
    u8 Checksum;
    char OEMID[6];
    char OEMTableID[8];
    u32 OEMRevision;
    u32 CreatorID;
    u32 CreatorRevision;
} _packed ACPISDTHeader;

typedef struct ACPI_RSDT
{
    ACPISDTHeader header;
    u32 entry;
} _packed ACPI_RSDT;

typedef struct ACPI_GenericAddressStructure
{
    u8 AddressSpace;
    u8 BitWidth;
    u8 BitOffset;
    u8 AccessSize;
    u64 Address;
}_packed ACPI_GenericAddressStructure;

typedef struct ACPI_FADT
{
    ACPISDTHeader header;
    u32 FirmwareCtrl;
    u32 Dsdt;

    // field used in ACPI 1.0; no longer in use, for compatibility only
    u8 Reserved;

    u8 PreferredPowerManagementProfile;
    u16 SCI_Interrupt;
    u32 SMI_CommandPort;
    u8 AcpiEnable;
    u8 AcpiDisable;
    u8 S4BIOS_REQ;
    u8 PSTATE_Control;
    u32 PM1aEventBlock;
    u32 PM1bEventBlock;
    u32 PM1aControlBlock;
    u32 PM1bControlBlock;
    u32 PM2ControlBlock;
    u32 PMTimerBlock;
    u32 GPE0Block;
    u32 GPE1Block;
    u8 PM1EventLength;
    u8 PM1ControlLength;
    u8 PM2ControlLength;
    u8 PMTimerLength;
    u8 GPE0Length;
    u8 GPE1Length;
    u8 GPE1Base;
    u8 CStateControl;
    u16 WorstC2Latency;
    u16 WorstC3Latency;
    u16 FlushSize;
    u16 FlushStride;
    u8 DutyOffset;
    u8 DutyWidth;
    u8 DayAlarm;
    u8 MonthAlarm;
    u8 Century;

    // reserved in ACPI 1.0; used since ACPI 2.0+
    u16 BootArchitectureFlags;

    u8 Reserved2;
    u32 Flags;

    // 12 byte structure; see below for details
    ACPI_GenericAddressStructure ResetReg;

    u8 ResetValue;
    u8 Reserved3[3];
  
    // 64bit pointers - Available on ACPI 2.0+
    u64 X_FirmwareControl;
    u64 X_Dsdt;

    ACPI_GenericAddressStructure X_PM1aEventBlock;
    ACPI_GenericAddressStructure X_PM1bEventBlock;
    ACPI_GenericAddressStructure X_PM1aControlBlock;
    ACPI_GenericAddressStructure X_PM1bControlBlock;
    ACPI_GenericAddressStructure X_PM2ControlBlock;
    ACPI_GenericAddressStructure X_PMTimerBlock;
    ACPI_GenericAddressStructure X_GPE0Block;
    ACPI_GenericAddressStructure X_GPE1Block;
} _packed ACPI_FADT;

// MADT 表
typedef struct ACPI_MADT
{
    ACPISDTHeader header;   // ACPI 标准表头
    u32 local_apic_address;   // 本地 APIC 的物理地址
    u32 flags;                // 标志位
    // 紧接着是变长的中断控制器结构体数组
} _packed ACPI_MADT;

// MADT 条目类型
#define MADT_LOCAL_APIC                    0x0
#define MADT_IO_APIC                       0x1
#define MADT_INTERRUPT_SOURCE_OVERRIDE     0x2
#define MADT_NMI_SOURCE                    0x3
#define MADT_LOCAL_APIC_NMI                0x4
#define MADT_LOCAL_APIC_ADDRESS_OVERRIDE   0x5
#define MADT_IO_SAPIC                      0x6
#define MADT_LOCAL_SAPIC                   0x7
#define MADT_PLATFORM_INTERRUPT_SOURCES    0x8
#define MADT_LOCAL_X2APIC                  0x9
#define MADT_LOCAL_X2APIC_NMI              0xA
#define MADT_GIC_CPU_INTERFACE             0xB
#define MADT_GIC_DISTRIBUTOR               0xC

// MADT 条目通用头部
typedef struct MADT_EntryHeader
{
    u8 type;       // 条目类型
    u8 length;     // 条目长度
} _packed MADT_EntryHeader;

// 处理器本地 APIC 结构体 (类型 0)
typedef struct MADT_LocalApic
{
    MADT_EntryHeader header;
    u8 processor_id;       // ACPI 处理器 ID
    u8 apic_id;            // APIC ID
    u32 flags;             // 标志位 (位 0 表示处理器是否启用)
} _packed MADT_LocalApic;

// I/O APIC 结构体 (类型 1)
typedef struct MADT_IOApic
{
    MADT_EntryHeader header;
    u8 io_apic_id;         // I/O APIC ID
    u8 reserved;
    u32 io_apic_address;   // I/O APIC 地址
    u32 global_system_interrupt_base; // 全局系统中断基址
} _packed MADT_IOApic;

// 中断源覆盖结构体 MADT_InterruptSourceOverride (类型 2)
typedef struct MADT_ISO
{
    MADT_EntryHeader header;
    u8 bus;                // 总线源
    u8 source;             // 中断源
    u32 global_system_interrupt; // 全局系统中断
    u16 flags;             // 标志位
} _packed MADT_ISO;

// NMI 源结构体 (类型 3)
typedef struct MADT_NmiSource
{
    MADT_EntryHeader header;
    u16 flags;             // 标志位
    u32 global_system_interrupt; // 全局系统中断
} _packed MADT_NmiSource;

// 本地 APIC NMI 结构体 (类型 4)
typedef struct MADT_LocalApicNmi
{
    MADT_EntryHeader header;
    u8 processor_id;       // ACPI 处理器 ID (0xFF 表示所有处理器)
    u16 flags;             // 标志位
    u8 lint;               // LINT# (0 或 1)
} _packed MADT_LocalApicNmi;

// 本地 APIC 地址覆盖结构体 MADT_LocalApicAddressOverride (类型 5)
typedef struct MADT_LAAO
{
    MADT_EntryHeader header;
    u16 reserved;
    u64 local_apic_address; // 64 位本地 APIC 地址
} _packed MADT_LAAO;

// 处理器本地 x2APIC 结构体 (类型 9)
typedef struct MADT_LocalX2Apic
{
    MADT_EntryHeader header;
    u16 reserved;
    u32 x2apic_id;         // x2APIC ID
    u32 flags;             // 标志位 (位 0 表示处理器是否启用)
    u32 processor_uid;     // ACPI 处理器 UID
} _packed MADT_LocalX2Apic;

// 本地 x2APIC NMI 结构体 (类型 A)
typedef struct MADT_LocalX2ApicNmi
{
    MADT_EntryHeader header;
    u16 flags;             // 标志位
    u32 processor_uid;     // ACPI 处理器 UID
    u8 lint;               // LINT# (0 或 1)
    u8 reserved[3];
} _packed MADT_LocalX2ApicNmi;

ACPISDTHeader *acpi_find_table(char *name);

#endif